﻿using System.Web.UI;
using System;
using System.Web.Caching;
using System.IO;

namespace YhmOA.Common
{
    #region 试图状态存放的位置
    /// <summary>
    /// 试图状态存放的位置
    /// </summary>
    public enum PageStatePersisterType
    {
        /// <summary>
        /// 将视图状态保存到缓存中
        /// </summary>
        Cache, 
        /// <summary>
        /// 将视图状态保存到页面上
        /// </summary>
        HiddenFiled
    }
    #endregion

    #region 获取试图状态保存的位置
    /// <summary>
    /// 获取试图状态保存的位置
    /// </summary>
    internal class PageStatePersisterFactory
    {
        public static PageStatePersister GetPageStatePersister(Page page, PageStatePersisterType type)
        {
            PageStatePersister pageStatePersister = null;
            switch (type)
            { 
                case PageStatePersisterType.Cache:
                    pageStatePersister = new PageStatePersisterCache(page);
                    break;
                case PageStatePersisterType.HiddenFiled:
                    pageStatePersister = new PageStatePersisterHiddenFiled(page);
                    break;
            }
            return pageStatePersister;
        }
    }
    #endregion

    #region 将缓存放在页面
    /// <summary>
    /// 将缓存放在页面
    /// </summary>
    internal class PageStatePersisterHiddenFiled : HiddenFieldPageStatePersister
    {
        public PageStatePersisterHiddenFiled(Page page) : base(page) { }

        public override void Save()
        {
            Pair pair = new Pair();
            if (base.ViewState != null)
            {
                pair.First = base.ViewState;
            }
            if (base.ControlState != null)
            {
                pair.Second = base.ControlState;
            }
            LosFormatter formatter = new LosFormatter();
            StringWriter output = new StringWriter();
            formatter.Serialize(output, pair);
            base.Page.ClientScript.RegisterHiddenField("__LPLVIEWSTATE", output.ToString());
            (base.Page as BasePage).Pretreatment.ServerMessageList.Add(new ServerMessage(ServerMessageType.ViewState,output.ToString()));
        }

        public override void Load()
        {
            string lplViewState = base.Page.Request["__LPLVIEWSTATE"] ?? "";
            if (lplViewState != "")
            {
                LosFormatter formatter = new LosFormatter();
                Pair pair = formatter.Deserialize(lplViewState.Replace(",", "").Replace(" ", "")) as Pair;
                base.ViewState = pair.First;
                base.ControlState = pair.Second;
            }
        }
    }
    #endregion

    #region 将试图状态保存在缓存中
    /// <summary>
    /// 将试图状态保存在缓存中
    /// </summary>
    internal class PageStatePersisterCache : LPLPageStatePersister
    {
        public PageStatePersisterCache(Page page) : base(page) { }

        public override void Save()
        {
            Pair pair = new Pair();
            if (base.ViewState != null)
            {
                pair.First = base.ViewState;
            }
            if (base.ControlState != null)
            {
                pair.Second = base.ControlState;
            }
            base.Page.Cache.Insert("__LPL__Cache_ViewState" + base.GetUniqueKey(), pair, null, DateTime.Now.AddMinutes(Convert.ToDouble(this.Timeout)), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
        }

        public override void Load()
        {
            if (base.Page.Cache.Count > 0 && base.Page.Cache.Get("__LPL__Cache_ViewState" + base.GetUniqueKey()) != null)
            {
                Pair pair = base.Page.Cache.Get("__LPL__Cache_ViewState" + base.GetUniqueKey()) as Pair;
                base.ViewState = pair.First;
                base.ControlState = pair.Second;
            }
        }

        /// <summary>
        /// 获取缓存失效的时间
        /// </summary>
        private int Timeout
        {
            get
            {
                int timeout = 20;
                if (base.Page.Session.Timeout > 0)
                {
                    timeout = base.Page.Session.Timeout;
                }
                return timeout;
            }
        }
    }
    #endregion

    #region 定义PageStatePersister的子类
    /// <summary>
    /// 定义PageStatePersister的子类
    /// </summary>
    internal class LPLPageStatePersister : PageStatePersister
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="page">当前页面</param>
        public LPLPageStatePersister(Page page) : base(page) { }

        /// <summary>
        /// 重写Load()事件，加载视图状态
        /// </summary>
        public override void Load()
        {
            
        }

        /// <summary>
        /// 重写Save()事件，保存视图状态
        /// </summary>
        public override void Save()
        {
            
        }

        /// <summary>
        /// 获取当前页面的唯一标示
        /// </summary>
        /// <returns>返回当前页面的唯一标示</returns>
        public string GetUniqueKey()
        {
            string uniqueKey = base.Page.Request["__LPLUNIQUEKEY"] ?? "";

            if (uniqueKey == "")
            {
                uniqueKey = base.Page.Session.SessionID + DateTime.Now.Ticks;
            }

            base.Page.ClientScript.RegisterHiddenField("__LPLUNIQUEKEY", uniqueKey);

            return uniqueKey;
        }
    }
    #endregion
}
